package com.zxmr.hospital.customer.action;

import com.alibaba.fastjson.JSON;
import com.zxmr.action.Request;
import com.zxmr.action.Response;
import com.zxmr.action.ResponsePayload;
import com.zxmr.action.ResultCode;
import com.zxmr.domain.Customer;
import com.zxmr.domain.Opportunity;
import com.zxmr.domain.account.AccountType;
import com.zxmr.domain.account.User;
import com.zxmr.domain.service.CustomerService;
import com.zxmr.domain.service.OpportunityService;
import com.zxmr.domain.service.UserService;
import com.zxmr.navigate.ExecuteException;
import com.zxmr.navigate.Executor;
import com.zxmr.util.ResourceManager;
import com.zxmr.util.UserTraceManager;
import com.zxmr.util.Utils;

public class OpportunityAction extends Executor{

	enum method{
		add,
		query,
		update,
	}
	@Override
	public void execute(Request request, Response response) {
		
		method method = Enum.valueOf(method.class, this.getElement().getMethod());
		try
		{
			
			switch(method)
			{
			case add:
				add(request,response);
				break;
			case query:
				query(request,response);
				break;
			case update:
				update(request,response);
			}

		}catch(Exception e)
		{
			ResponsePayload payload = new ResponsePayload();
			if(e instanceof ExecuteException)
			{
				payload.setValue(e.getMessage());
			}else
			{
				e.printStackTrace();
				payload.setValue("internal error");
			}
			response.setPayload(payload);
			response.setResult(ResultCode.COMPONENT_ERROR);
		}
	}

	private void add(Request request,Response response)throws ExecuteException
	{
		Opportunity opp = parseRequestToOpportunity(request);

		validateOpportunityName(opp.getName());
		validateCustomer(opp.getCustomer(),request.getAccount());
		
		opp.setCompany(request.getAccount().getCompany());
		opp.setCreateTime(Utils.getCurrentTime());
		opp.setOwner(request.getAccount().getName());
		
		OpportunityService service = new OpportunityService();
		if(!service.addOpportunity(opp))
			this.internalErrorResponse(response);
		else
		{
			String action = ResourceManager.getInstance().getMessage("com.zxmr.customer.addOpportunity",opp.getCustomerName(),opp.getItems());
			UserTraceManager.addTrace(action, request.getAccount());
		}
	}
	private void validateCustomer(int customer,User user)throws ExecuteException
	{
		CustomerService service = new CustomerService();
		Customer cus = service.queryCustomer(customer);
		if(cus == null || cus.getCompany() != user.getCompany())
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.misCustomer"));
	}
	private void validateOpportunityName(String name)throws ExecuteException
	{
		if(Utils.isStringEmptyWithTrim(name))
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.opportunity.notitle"));
	}
	private Opportunity parseRequestToOpportunity(Request request)throws ExecuteException
	{
		try
		{
			return JSON.parseObject(request.getRequestParameters().get("parameters"), Opportunity.class);
		}catch(Exception e)
		{
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.errorPara"));
		}
	}
	private void query(Request request,Response response)throws ExecuteException
	{
		long id = getQueryId(request);

		OpportunityService service = new OpportunityService();
		Opportunity opp = service.queryOpportunity(id);
		if(opp == null || opp.getCompany()!= request.getAccount().getCompany())
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.noauth"));
		
		if(request.getAccount().getAccountType()!= AccountType.Supervisor &&
				!request.getAccount().getName().equals(opp.getOwner()))
		{
			if(!this.isAuthorized(request.getAccount().getId(), "queryOpportunityOthers"))
				throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.noauth.queryOpportunityOthers"));
		}
		
		ResponsePayload payload = new ResponsePayload(JSON.toJSONString(opp));
		response.setPayload(payload);
		
	}
	private long getQueryId(Request request)throws ExecuteException
	{
		String idString = request.getRequestParameters().get("id");
		try
		{
			return Long.parseLong(idString);
		}catch(Exception e)
		{
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.errorPara"));
		}
	}
	private void update(Request request,Response response)throws ExecuteException
	{
		Opportunity opp = parseRequestToOpportunity(request);

		OpportunityService service = new OpportunityService();
		Opportunity orign = service.queryOpportunity(opp.getId());
		
		if(orign == null || orign.getCompany()!= request.getAccount().getCompany())
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.noauth"));
		
		validateUpdateStatus(orign,opp);
		validateOpportunityName(opp.getName());
		validateCustomer(opp.getCustomer(),request.getAccount());
		validateOwner(opp.getOwner(),request.getAccount());
		
		if(!service.updateOpportunity(opp))
			this.internalErrorResponse(response);
		else
		{
			String action = ResourceManager.getInstance().getMessage("com.zxmr.customer.updateOpportunity",opp.getCustomerName(),opp.getItems());
			UserTraceManager.addTrace(action, request.getAccount());
		}
	}
	
	private void validateUpdateStatus(Opportunity orign,Opportunity update)throws ExecuteException
	{
		if(orign.getStrategy().getIndex() > update.getStrategy().getIndex())
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.opportunity.strategyupdate"));
	}
	private void validateOwner(String owner,User user)throws ExecuteException
	{
		UserService service = new UserService();
		User o = service.findUser(owner);
		if(o == null || o.getCompany() != user.getCompany())
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.misCustomer"));
	}
	
}
